<?php
// Module Body

function unix_users_info(&$data) {
	global $personaldata, $T;

	$unique = get_property('unix user', $personaldata['id'], $personaldata['username']);
	if($unique==NULL) {
		$unique = $T['na'];
	}

	$data[] = array('name' => $T['UNIX Username'], 'value' => $unique);
}

function virtual2unique(&$data) {
	// Try to generate a unique username
	$domaindata = fetchdata('domain', 'domain', $data['id']);
	$short_domain = substr(strtok($domaindata['domain'], '.'), 0, 16);
	$unique = substr($short_domain.'_'.$data['username'], 0, 31);

	$res = mysql_query('SELECT `id` FROM `properties` WHERE `name` = '
		.'"unix user" AND `value` = "'.$unique.'" LIMIT 1');
	$i = 1;
	while(mysql_num_rows($res)>0 || user_exists($unique)) {
		$unique = substr($unique, 0, 31-strlen($i)).$i;

		$res = mysql_query('SELECT `id` FROM `properties` WHERE `name` = '
			.'"unix user" AND `value` = "'.$unique.'" LIMIT 1');
	}

	return $unique;
}

function unix_users_create_linux(&$data) {
	global $cfg;

	$unique = virtual2unique($data);

	set_property('unix user', $unique, $data['id'], $data['username']);

	if(!is_dir($data['root'])) {
		// Recursively create directory
		$ar = explode('/', $data['root']);
		// array_shift($dir); Is this line even used?
		$dir = '';

		foreach($ar as $sub) {
			if(is_readable($dir) && !is_dir($dir.'/'.$sub)) {
				mkdir($dir.'/'.$sub, 0775);
			}
			$dir .= '/'.$sub;
		}

		if(!is_dir($data['root'])) {
			webcp_log(1,0,"system","User Creation Error: Home directory "
				.$data['root']." does not exist and cannot be created.",0);
			return;
		}
	}

        //Correct verification of md5 usage to allow for Debian based & RH based systems
        //Debian does NOT use /etc/sysconfig/authconfig
	//original code taken from user.wcp.phps
	//see if MD5 passwords are enabled, otherwise use DES (checked on redhat 7.1 - 9.0)
        if(strtolower($cfg['osversion']) == "debian"){
            $filearray = file ($cfg['pam.d_password']);
            $newarray = array();

            foreach ($filearray as $pamkey => $pamline ){
                if(stristr( $pamline, "md5") && !stristr($pamline,"#")){
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
                    break;
                }else $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }elseif(strtolower($cfg['osversion']) == "slackware"){
            $filearray = file ($cfg['login.defs']);
            $newarray = array();

            foreach ($filearray as $pamkey => $pamline ){
                if(stristr( $pamline, "MD5_CRYPT_ENAB") && !stristr($pamline,"#") && stristr(strtolower($pamline), "yes")){
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
                    break;
                }else $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }else{
            if (is_readable($cfg['authconfig'])	&& strpos(file_get_contents($cfg['authconfig']), 'USEMD5=yes')!==false) {
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
            } else {
                    $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }

	// Set appropriate shell
	if ($data['shell'] == "on")
		$shell = $cfg['prog']['shell'];
	else
		$shell = $cfg['prog']['noshell'];

	$data['name'] = addslashes($data['name']);

	$createuser = $cfg['prog']['uadd'].' -g g'.$data['id'].' -d "'.$data['root'].'" -s '
		.$shell.' -c "'.$data['name'].'" -p \''.$crypt_password.'\' '.$unique;
	exec($createuser);

}

function unix_users_create_bsd(&$data) {
	global $cfg;

	$unique = virtual2unique($data);

	set_property('unix user', $unique, $data['id'], $data['username']);

	if(!is_dir($data['root'])) {
		// Recursively create directory
		$ar = explode('/', $data['root']);
		// array_shift($dir); Is this line even used?
		$dir = '';

		foreach($ar as $sub) {
			if(is_readable($dir) && !is_dir($dir.'/'.$sub)) {
				mkdir($dir.'/'.$sub, 0775);
			}
			$dir .= '/'.$sub;
		}

		if(!is_dir($data['root'])) {
			webcp_log(1,0,"system","User Creation Error: Home directory "
				.$data['root']." does not exist and cannot be created.",0);
			return;
		}
	}


	// Set appropriate shell
	if ($data['shell'] == "on")
		$shell = $cfg['prog']['shell'];
	else
		$shell = $cfg['prog']['noshell'];

	$data['name'] = addslashes($data['name']);

	/*
		To add a user on FreeBSD:
		echo "password" | pw adduser user -g group \
		-s shell -d /home/user -c comment -h -

		adds the user 'user' with primary group 'group',
		shell 'shell', home dir '/home/user' with a comment 'comment'

		This is pretty dodgy - the password is listed in ps output...

		To do this from PHP though, we use popen to create a stream to the
		command:
		pw adduser -q -u user -g group \
		-s shell -d /home/user -c comment -h 0

		and then write the password to the file pointer created
		by popen.  This effectively adds the user to the passwd database
		whilst at same time setting the password.

		This saves listing the password in 'ps' listings.
	*/
	// adduser command:
	$pw_cmd = $cfg['prog']['pw']." useradd ".$unique
			." -g g".$data["id"]
			." -s $shell "
			." -d ".$data["root"]
			." -c \"".$data["name"]."\""
			." -h 0";

	// Open a uni-directional stream to the command:
	$fp = popen($pw_cmd, "w");

	// Execute the command, passing the $data["password"] to it:
	fwrite($fp, $data["password"]);

	// Close the pipe:
	fclose($fp);

}

function unix_users_remove_linux(&$data) {
	global $cfg;
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['udel']." '".$unique."'");
}

function unix_users_remove_bsd(&$data) {
	global $cfg;
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['pw']." userdel -n ".$unique);
}

function unix_users_update_linux(&$data) {
	global $cfg;

	$prevunique = get_property('unix user', $data['id'], $data['username1']);

	if ($data['username'] != $data['username1']) {
		set_property('unix user', '', $data['id'], $data['username']);
		$unique = virtual2unique($data['username']);
		set_property('unix user', $unique, $data['id'], $data['username']);
	} else {
		$unique = get_property('unix user', $data['id'], $data['username']);
	}

        //Correct verification of md5 usage to allow for Debian based & RH based systems
        //Debian does NOT use /etc/sysconfig/authconfig
	//original code taken from user.wcp.phps
	//see if MD5 passwords are enabled, otherwise use DES (checked on redhat 7.1 - 9.0)
        if(strtolower($cfg['osversion']) == "debian"){
            $filearray = file ($cfg['pam.d_password']);
            $newarray = array();

            foreach ($filearray as $pamkey => $pamline ){
                if(stristr( $pamline, "md5") && !stristr($pamline,"#")){
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
                    break;
                }else $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }elseif(strtolower($cfg['osversion']) == "slackware"){
            $filearray = file ($cfg['login.defs']);
            $newarray = array();

            foreach ($filearray as $pamkey => $pamline ){
                if(stristr( $pamline, "MD5_CRYPT_ENAB") && !stristr($pamline,"#") && stristr(strtolower($pamline), "yes")){
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
                    break;
                }else $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }else{
            if (is_readable($cfg['authconfig'])	&& strpos(file_get_contents($cfg['authconfig']), 'USEMD5=yes')!==false) {
                    $crypt_password = crypt($data['password'], '$1$'.make_salt().'$');
            } else {
                    $crypt_password = crypt($data['password'], $cfg['key']);
            }
        }

	// Set appropriate shell
	if ($data['shell'] == "on")
		$shell = $cfg['prog']['shell'];
	else
		$shell = $cfg['prog']['noshell'];

	$data['name'] = addslashes($data['name']);

	if ($unique != $prevunique) {
	    $username_changed = '-l \''.$unique.'\'';
	} else {
	    $username_changed = '';
	}

	exec($cfg['prog']['umod']." $username_changed -d '$data[root]' -s $shell "
		."-c '$data[name]' -p '$crypt_password' '$prevunique'");

}

function unix_users_update_bsd(&$data) {
	global $cfg;

	$prevunique = get_property('unix user', $data['id'], $data['user']);

	if ($data['username'] != $data['username1']) {
		set_property('unix user', '', $data['id'], $data['user']);
		$unique = virtual2unique($data['username']);
		set_property('unix user', $unique, $data['id'], $data['user']);
	} else {
		$unique = get_property('unix user', $data['id'], $data['user']);
	}

	// Set appropriate shell
	if ($data['shell'] == "on")
		$shell = $cfg['prog']['shell'];
	else
		$shell = $cfg['prog']['noshell'];

	$data['name'] = addslashes($data['name']);

	$pw_cmd = $cfg['prog']['pw']." usermod -q -n ".$prevunique." -l ".$unique
						." -g g".$data["id"]
						." -s $shell "
						." -d ".$data["root"]
						." -c \"".$data["name"]."\""
						." -h 0";

	// Open a uni-directional stream to the command:
	$fp=popen($pw_cmd, "w");

	// Execute the command, passing the $data["password"] to it:
	fwrite($fp, $data["password"]);

	// Close the pipe:
	fclose($fp);

}

function unix_users_suspend_linux(&$data) {
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['umod']." -L '".$unique."'");
}

function unix_users_suspend_bsd(&$data) {
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['pw']." lock $unique");
}

function unix_users_unsuspend_linux(&$data) {
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['umod']." -U '".$unique."'");
}

function unix_users_unsuspend_bsd(&$data) {
	$unique = get_property('unix user', $data['id'], $data['username']);
	exec($cfg['prog']['pw']." unlock $unique");
}

function unix_username(&$data) {
	$unique = get_property('unix user', $data['id'], $data['username']);
	if ($unique != '') {
		$data['username'] = $unique;
	}
}
?>
